package com.tian.controller;

import com.tian.annotation.SysLogAnnotation;
import com.tian.enums.SysLogTypeEnum;
import com.tian.strategy.CalculateDiscountAmountService;
import com.tian.strategy.CalculateDiscountAmountStrategy;
import org.redisson.api.RList;
import org.redisson.api.RScript;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * {@code @description:} TODO
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024-08-20 21:14
 * {@code @version:} 1.0
 */
@RestController
@RequestMapping("/test")
public class Test {
    @Resource
    private RedissonClient redissonClient;
    ExecutorService executorService = Executors.newFixedThreadPool(1000);

    private final static String LOCK_KEY = "seconds:skill:1111111";

    //初始化数据
    @GetMapping("/init")
    public void init() {
        RList<Integer> list = redissonClient.getList(LOCK_KEY);
        // 库存 缓存到redis 中  ----10张优惠券
        for (int i = 0; i < 10; i++) {
            list.add(1);
        }
    }

    //模拟1000个线程去抢优惠券
    @GetMapping("/secondsSkill")
    public void secondsSkill() {
        AtomicInteger successNum = new AtomicInteger(0);
        AtomicInteger failNum = new AtomicInteger(0);
        CountDownLatch countDownLatch = new CountDownLatch(1000);
        for (int i = 0; i < 1000; i++) {
            executorService.execute(() -> {
                String luaScript = "if redis.call('lpop', KEYS[1]) then return 1 else return 0 end";

                List<Object> keys = new ArrayList<>();
                keys.add(LOCK_KEY);

                Long result = redissonClient.getScript().eval(RScript.Mode.READ_WRITE, luaScript, RScript.ReturnType.INTEGER, keys);

                if (result == 1L) {
                    System.out.println("兑换成功");
                    successNum.getAndIncrement();
                } else {
                    System.out.println("兑换失败");
                    failNum.getAndIncrement();
                }
                countDownLatch.countDown();
            });
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("兑换成功：" + successNum.get());
        System.out.println("兑换失败：" + failNum.get());
    }

    @GetMapping("/test")
    @SysLogAnnotation(methodDescription = "测试日志--GET", type = SysLogTypeEnum.FILE)
    public String testSysLog(@RequestParam("name") String name) {
        System.out.println("测试系统日志" + name);
        return "success";
    }



    @GetMapping("/test2")
    public String test2() {
        BigDecimal amount = new BigDecimal("200.99");//200.99-20.099= 180.891
        BigDecimal faceAmount = new BigDecimal("1");
        int type = 2;
        CalculateDiscountAmountService service = CalculateDiscountAmountStrategy.getCalculateDiscountAmountService(type);
        BigDecimal bigDecimal = service.calculateDiscountAmount(amount, faceAmount);
        System.out.println(bigDecimal);
        return "success";
    }

}
